#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h> 
#include <assert.h> 
#include <stdint.h>


int main(int argc, char *argv[]) {

  int fd=0;
  unsigned int batch=1;
  unsigned int skip=0;
  unsigned int count=10;
  uint64_t* buf=NULL;
  unsigned int idx=0;
  int loc=0;
  unsigned int i;
  int amt_written=0;
  int amt_read=0;

  //  printf("Testing read and write correctness.\n");

  assert(argc==5 && "Args are <file> <batch> <skip> <count>");

  batch = atoi(argv[2]);
  skip = atoi(argv[3]);
  count = atoi(argv[4]);

  //Do the writes...
  fd = creat(argv[1], S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
  assert(fd>0 && "Couldn't open the target file.");

  buf = calloc(batch,sizeof(uint64_t));
  assert(buf && "Couldn't allocate memory.");
  
  loc = lseek(fd, skip, SEEK_SET);
  assert(loc==skip && "Couldn't seek to the desired byte offset for writes.");

  while( idx < count*batch ) {
    for(i=0; i < batch; ++i) {
      buf[i] = idx;
      idx=idx+1;
    }
    amt_written = write(fd, buf, sizeof(uint64_t)*batch);  
    assert(amt_written ==sizeof(uint64_t)*batch && "Failed to write data.");
  }

  close(fd);

  //Are they still right?
  fd = open(argv[1], O_RDONLY);
  assert(fd>0 && "Couldn't open file for reading.");

  loc = lseek(fd, skip, SEEK_SET);
  assert(loc==skip && "Couldn't seek to the desired byte offset for reads.");

  while( idx < count*batch ) {
    amt_read = read(fd, buf, sizeof(uint64_t)*batch);  
    assert(amt_read ==sizeof(uint64_t)*batch && "Failed to read data.");

    for(i=0; i < batch; ++i) {
      if(buf[i] != idx) {
	printf("Found invalid data!\n");
	exit(-1);
      }
      idx=idx+1;
    }
  }

  close(fd);

  //  printf("pass.\n");
  free(buf);
  return 0;
}
